﻿using System;
using System.Collections.Concurrent;
using System.ComponentModel;
using System.Linq;

namespace HobSoft.SoccerBet2014.Domain.Common.SiteContext
{
    using sm = Domain.Models.Site;
    public class ContextManager
    {
        static ConcurrentDictionary<ContextBase, sm.SiteContext> registerContextTable = new ConcurrentDictionary<ContextBase, sm.SiteContext>();
        public static Context<T> Register<T>(byte bookerId, string account, string modelKey, string key) where T : struct
        {
            sm.SiteContext pctx = new sm.SiteContext(bookerId, account, modelKey, key);
            Context<T> context = new Context<T>(pctx);
            context.PropertyChanged += Context_PropertyChanged;
            registerContextTable.AddOrUpdate(context, pctx, (k, old) => pctx);
            return context;
        }

        public static Context Register(byte bookerId, string account, string modelKey, string key)
        {
            sm.SiteContext pctx = new sm.SiteContext(bookerId, account, modelKey, key);
            Context context = new Context(pctx);
            context.PropertyChanged += Context_PropertyChanged;
            registerContextTable.AddOrUpdate(context, pctx, (k, old) => pctx);
            return context;
        }

        private static void Context_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (Repository == null) return;
            var ctxObj = (ContextBase)sender;
            if (!registerContextTable.ContainsKey(ctxObj))
                return;
            var ctx = registerContextTable[ctxObj];
            ctx.ContextValue = sender.ToString();
            ctx.LastUpdate = DateTime.Now;
            Repository.AddOrUpdate(ctx);
        }

        public static void RecoverContext(byte bookerId, string account, DateTime lastUpdate)
        {
            if (Repository == null) return;

            var q = registerContextTable.Where(c => c.Value.Check(bookerId, account));
            foreach (var ctx in q)
            {
                var pctx = Repository.Get(ctx.Value.Key);
                if (pctx != null && pctx.LastUpdate > lastUpdate)
                {
                    ctx.Value.RecoverContextValue(pctx.ContextValue);
                }
            }

        }

        public static ISiteContextRepository Repository
        {
            get;
            set;
        }

    }
}
